//
//  EAGLView.m
//  TestApp
//
//  Created by liu dingxi on 09-7-30.
//  Copyright tencent 2009. All rights reserved.
//



#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
#include <AudioToolbox/AudioToolbox.h>

#import "EAGLView.h"
#import "GameFrame.h"


int IsDirectoryA(const char*);
int FileExistsA(const char*);

#define USE_DEPTH_BUFFER 0

@implementation GUIEditor
@synthesize pFocus;
@end


// A class extension to declare private methods
@interface EAGLView ()

@property (nonatomic, retain) EAGLContext *context;
@property (nonatomic, assign) NSTimer *animationTimer;

- (BOOL) createFramebuffer;
- (void) destroyFramebuffer;

@end


@implementation EAGLView

@synthesize context;
@synthesize animationTimer;
@synthesize animationInterval;
@synthesize m_pEditor;

+(NSString *) HomePath
{
	return NSHomeDirectory();
}

+(NSString *) TempPath
{
	//#if	TARGET_IPHONE_SIMULATOR
	//return @"../tmp";
	//#if (TARGET_IPHONE_SIMULATOR_USER == 1)	
	NSString *path = [NSTemporaryDirectory() stringByStandardizingPath];
	return path;	
}

+(NSString *) DocPath
{
	//#if (TARGET_IPHONE_SIMULATOR_USER == 1)	
	//#if	TARGET_IPHONE_SIMULATOR
	{
		
		NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
		NSString *documentsDirectory = [paths objectAtIndex:0];
		return documentsDirectory;	
	}
	//#else	
	
	//	return @"/var/tmp";
	//@"/Applications/QQGame.app/Documents"
	//#endif
}

+(NSString *) AppPath
{
	
	//#if (TARGET_IPHONE_SIMULATOR_USER == 1)
	//#if	TARGET_IPHONE_SIMULATOR
	NSString* strPath =  [NSString stringWithFormat:@"%@/QQLink.app", NSHomeDirectory()];
	//NSRange rangeFind = [ strPath rangeOfString:@"/var/mobile/QQGame.app"];
	
	//if ( rangeFind.location == 0 )
	if ( [strPath compare:@"/var/mobile/QQLink.app" ] == NSOrderedSame )
	{
		return @"/Applications/QQLink.app";
	}
	return strPath;
}


- (void)bindEditor:(FOCUS_EDIT*)pFocus
{
	if(m_pEditor == NULL)
	{
		CGFloat fsize = [UIFont systemFontSize];
		CGRect rEdit = CGRectMake(0, 0, 100, fsize);
		m_pEditor = [[GUIEditor alloc] initWithFrame:rEdit];
		m_pEditor.pFocus = NULL;
		
		m_pEditor.borderStyle = UITextBorderStyleNone;
		m_pEditor.textColor = [UIColor blackColor];
		m_pEditor.font = [UIFont systemFontOfSize:fsize];
		m_pEditor.placeholder = nil;
		//m_pEditor.backgroundColor = [UIColor whiteColor];
		m_pEditor.autocorrectionType = UITextAutocorrectionTypeNo;	// no auto correction support
		
		m_pEditor.keyboardType = UIKeyboardTypeDefault;	// use the default type input method (entire keyboard)
		m_pEditor.returnKeyType = UIReturnKeyDone;
		
		m_pEditor.clearButtonMode = UITextFieldViewModeWhileEditing;	// has a clear 'x' button to the right
		
		m_pEditor.delegate = self;
		
		[self addSubview:m_pEditor];
	}
	
	if(pFocus)
	{
		m_pEditor.pFocus = pFocus;
		if(pFocus->nType == ETYPE_DEFAULT)
		{
			CGRect frame = m_pEditor.frame;
			frame.origin.x = pFocus->x;
			frame.origin.y = pFocus->y;
			frame.size.width = pFocus->nWidth;
			frame.size.height = pFocus->nHeight;
			[m_pEditor setFrame:frame];
			m_pEditor.hidden = NO;
			m_pEditor.text = @"";
			
			CGFloat fsize = [UIFont systemFontSize];
			if(pFocus->nFontSize > 0)
			{
				fsize = (CGFloat)(pFocus->nFontSize);
			}
			m_pEditor.font = [UIFont systemFontOfSize:fsize];
			
			CGFloat r = ((CGFloat)(pFocus->nColor & 0xFF)/255.0);
			CGFloat g = ((CGFloat)((pFocus->nColor >> 8) & 0xFF)/255.0);
			CGFloat b = ((CGFloat)((pFocus->nColor >> 16) & 0xFF)/255.0);
			m_pEditor.textColor = [UIColor colorWithRed:r green:g blue:b alpha:1.0];
						
			if(pFocus->pBuffer && pFocus->nText)
			{
				m_pEditor.text = [[NSString alloc] initWithBytes:pFocus->pBuffer
											length:pFocus->nText encoding:NSUTF8StringEncoding ] ;
			}
		}
		else
		{
			m_pEditor.text = @"E";
			m_pEditor.hidden = YES;
		}
		
		int nBeforeType = m_pEditor.keyboardType;
		if(pFocus->nType == ETYPE_DIGIT)
		{
			m_pEditor.keyboardType = UIKeyboardTypeNumberPad;
		}
		else
		{
			m_pEditor.keyboardType = UIKeyboardTypeDefault;
		}
		if(nBeforeType != m_pEditor.keyboardType)
		{
			[m_pEditor resignFirstResponder];
		}
		
		[m_pEditor becomeFirstResponder];		
	}
	else //pFocus == NULL kill focus
	{
		if(m_pEditor.pFocus)
		{
			pFocus = m_pEditor.pFocus;
			
			unsigned long lParam1 = 0;
			unsigned long lParam2 = (unsigned long)pFocus;
			
			if(pFocus->nType == ETYPE_DEFAULT)
			{
				const char* pText = [m_pEditor.text UTF8String];
				if(pText && pFocus->pBuffer && pFocus->nBuffer > 0)
				{
					int nText = strlen(pText);
					if(nText < pFocus->nBuffer)
					{
						if(nText == pFocus->nText)
						{
							if(strncmp(pText, pFocus->pBuffer, nText) != 0)
							{
								lParam1 = 1;
							}
						}
						else
						{
							lParam1 = 1;
						}
						if(lParam1 != 0)
						{
							strcpy(pFocus->pBuffer, pText);
							pFocus->nText = nText;
						}
					}
				}
			}
			GameMessage(MSG_EDITOR_TEXT, lParam1, lParam2);
		}
		m_pEditor.pFocus = NULL;
		m_pEditor.hidden = YES;
		if([m_pEditor isFirstResponder])
		{
			[m_pEditor resignFirstResponder];
		}	
		GameMessage(MSG_LBUTTONDOWN, 0, 0);
	}
}


#pragma mark -
#pragma mark UITextFieldDelegate

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
	if(m_pEditor && m_pEditor.pFocus)
	{
		if(m_pEditor.pFocus->nType != ETYPE_DEFAULT)
		{
			textField.hidden = YES;
		}
	}
}


-(void)textFieldDidEndEditing:(UITextField *)textField
{
}

-(BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
	if(m_pEditor && m_pEditor.pFocus)
	{
		if(m_pEditor.pFocus->nType != ETYPE_DEFAULT)
		{
			if(string)
			{
				unsigned long lParam1 = 0;
				if([string length] == 0)
				{
					lParam1 = VK_BACK;
				}
				else
				{
					lParam1 = [string characterAtIndex:0];
				}
				
				GameMessage(MSG_KEYCHAR, lParam1, 0);
			}	
			return NO;
		}
		else
		{
			if(textField.text)
			{
				int nMaxLength = m_pEditor.pFocus->nMaxLength;
				if(nMaxLength == 0 || nMaxLength > m_pEditor.pFocus->nBuffer)
				{
					nMaxLength = m_pEditor.pFocus->nBuffer - 2;
				}
				const char* pText = [textField.text UTF8String];
				int nText = strlen(pText);
				if(nText > nMaxLength)
					return NO;
			}
		}

	}
	return YES;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
	// the user pressed the "Done" button, so dismiss the keyboard
	[self bindEditor:0];
	
	[textField resignFirstResponder];
	return YES;
}

#pragma mark -
#pragma mark Text Fields


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	for (UITouch * touch in touches)
	{
		CGPoint location = [touch locationInView:self];
	
		int x = location.x;
		int y = location.y;
		unsigned long lParam2 = y;
		lParam2 = (lParam2 << 16) + x;
		unsigned long lParam1 = 0;
		
		int ret = GameMessage(MSG_LBUTTONDOWN, lParam1, lParam2);
		switch(ret)
		{
			case NTF_EDIT_FOCUS:
			{
				FOCUS_EDIT* pFocus = GameFocusEdit();
				[self bindEditor:pFocus];
			}
				break;
			case NTF_KILL_FOCUS:
				[self bindEditor:0];
				break;
		}
	}	
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{  
	for (UITouch * touch in touches)
	{
		CGPoint location = [touch locationInView:self];
		
		int x = location.x;
		int y = location.y;
		unsigned long lParam2 = y;
		lParam2 = (lParam2 << 16) + x;
		unsigned long lParam1 = 0;
		
		GameMessage(MSG_MOUSEMOVE, lParam1, lParam2);
	}	

}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
	for (UITouch * touch in touches)
	{
		CGPoint location = [touch locationInView:self];
		
		int x = location.x;
		int y = location.y;
		unsigned long lParam2 = y;
		lParam2 = (lParam2 << 16) + x;
		unsigned long lParam1 = 0;
		
		GameMessage(MSG_LBUTTONUP, lParam1, lParam2);
	}	
}

// You must implement this method
+ (Class)layerClass {
    return [CAEAGLLayer class];
}


//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder {
    
    if ((self = [super initWithCoder:coder])) {
        // Get the layer
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
        
        eaglLayer.opaque = YES;
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
        
        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
        
        if (!context || ![EAGLContext setCurrentContext:context]) {
            [self release];
            return nil;
        }
       
		const char* szPath = [[EAGLView AppPath] UTF8String];
		if(szPath)
		{
			char szFolder[256];
			strcpy(szFolder, szPath);
			strcat(szFolder, "/bin/");
			
			if(!IsDirectoryA(szFolder))
			{
				return nil;
			}
			
			GameInit(szFolder);
		}
		
		
		[[UIApplication sharedApplication] setStatusBarHidden:YES];
		
	
		AudioServicesPlaySystemSound(0);
		
        animationInterval = 1.0 / 10.0;
    }
    return self;
}


- (void)drawView {
    
    // Replace the implementation of this method to do your own custom drawing
    
     
    [EAGLContext setCurrentContext:context];
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    //glViewport(0, 0, backingWidth, backingHeight);
    
    //glMatrixMode(GL_PROJECTION);
    //glLoadIdentity();
    //glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
    //glMatrixMode(GL_MODELVIEW);
	
	GameRender();
    
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}


- (void)layoutSubviews {
    [EAGLContext setCurrentContext:context];
    [self destroyFramebuffer];
    [self createFramebuffer];
    [self drawView];
}


- (BOOL)createFramebuffer {
    
    glGenFramebuffersOES(1, &viewFramebuffer);
    glGenRenderbuffersOES(1, &viewRenderbuffer);
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
    
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
    
    if (USE_DEPTH_BUFFER) {
        glGenRenderbuffersOES(1, &depthRenderbuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    }
    
    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
        NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
        return NO;
    }
    
    return YES;
}


- (void)destroyFramebuffer {
    
    glDeleteFramebuffersOES(1, &viewFramebuffer);
    viewFramebuffer = 0;
    glDeleteRenderbuffersOES(1, &viewRenderbuffer);
    viewRenderbuffer = 0;
    
    if(depthRenderbuffer) {
        glDeleteRenderbuffersOES(1, &depthRenderbuffer);
        depthRenderbuffer = 0;
    }
}


- (void)startAnimation {
    self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(OnTimer) userInfo:nil repeats:YES];
}


- (void)stopAnimation {
    self.animationTimer = nil;
}


- (void)setAnimationTimer:(NSTimer *)newTimer {
    [animationTimer invalidate];
    animationTimer = newTimer;
}


- (void)setAnimationInterval:(NSTimeInterval)interval {
    
    animationInterval = interval;
    if (animationTimer) {
        [self stopAnimation];
        [self startAnimation];
    }
}

- (void)OnTimer {
	GameUpdate(100);
	[self drawView];
}

- (void)OnQuit {
	[self stopAnimation];
	GameFree();
}


- (void)dealloc {
    
    [self stopAnimation];
    
    if ([EAGLContext currentContext] == context) {
        [EAGLContext setCurrentContext:nil];
    }
    
    [context release];  
    [super dealloc];
}

@end
